using System;
using Firestarter.DB.Schema.BO;
using Firestarter.DB.Schema.Logic;
using FireStarterModeller.BO;

namespace FireStarterModeller.Test
{
    public class DBTableBuilder
    {
        private readonly DBTable _dbTable;

        public DBTableBuilder(DBTable dbTable)
        {
            _dbTable = dbTable;
        }

        public DBTable Table
        {
            get { return _dbTable; }
        }

        
        public DBPrimaryKey AddPrimaryKey(params string[] columnNames)
        {
            DBPrimaryKey dbPrimaryKey = new DBPrimaryKey();
            _dbTable.PrimaryKeyDB = dbPrimaryKey;
            foreach (string columnName in columnNames)
            {
                DBColumn dbColumn = AddColumn(columnName);
                dbColumn.Nullable = false;
                dbPrimaryKey.AddColumnInfo(dbColumn);
            }
            return dbPrimaryKey;
        }

        public DBPrimaryKeyColumn AddPrimaryKeyColumn()
        {
            return AddPrimaryKeyColumn(_dbTable.TableName + "ID");
        }

        public DBPrimaryKeyColumn AddPrimaryKeyColumn(string columnName)
        {
            DBColumn dbColumn = AddColumnOfIdType(columnName);
            return AddPrimaryKeyColumn(dbColumn);
        }

        public DBPrimaryKeyColumn AddPrimaryKeyColumn(string columnName, string dataType, int dataLength)
        {
            DBColumn dbColumn = AddColumn(columnName, dataType, dataLength);
            return AddPrimaryKeyColumn(dbColumn);
        }

        private DBPrimaryKeyColumn AddPrimaryKeyColumn(DBColumn column)
        {
            column.Nullable = false;
            if (_dbTable.PrimaryKeyDB == null) _dbTable.PrimaryKeyDB = new DBPrimaryKey();
            return _dbTable.PrimaryKeyDB.AddColumnInfo(column);
        }

        private DBColumn AddColumnOfIdType(string columnName)
        {
            return AddColumn(columnName, "CHAR", 38);
        }

        public DBColumn AddColumn(string columnName)
        {
            return AddColumn(columnName, "VARCHAR", 50);
        }

        public DBColumn AddColumn(string columnName, string dataType, int dataLength)
        {
            DBColumn dbColumn = new DBColumn(columnName)
                                    {
                                        DataType =  dataType,
                                        DataLength = dataLength,
                                        Nullable = true
                                    };
            _dbTable.Columns.Add(dbColumn);
            dbColumn.OrdinalPosition = _dbTable.Columns.Count;
            return dbColumn;
        }

        public void AddAutoIncrementingColumn()
        {
            var dbColumn = new DBColumn("AutoIncrementingColumn")
            {
                DataType = DBDataTypes.INTEGER,
                DataLength = 1,
                Nullable = false,
                IsAutoIncrementing = false
            };
            _dbTable.Columns.Add(dbColumn);
            dbColumn.OrdinalPosition = _dbTable.Columns.Count;
        }

        public DBColumn AddColumnWithAllPropsSet()
        {
            var dbColumn = new DBColumn("DBColumnName")
                                    {
                                        DataType = DBDataTypes.TEXT,
                                        DataLength = 2,
                                        Nullable = true,
                                        OrdinalPosition = 5,
                                        IsAutoIncrementing = false,
                                        DefaultValue = "DBColumnDefaultValue",
                                        Comment = "DBColumnComment"
                                    };
            _dbTable.Columns.Add(dbColumn);
            return dbColumn;
        }

        public DBForeignKey AddForeignKey(string foreignKeyName, DBTable parentDBTable)
        {
            var dbForeignKey = new DBForeignKey
                                            {
                                                ForeignKeyName = foreignKeyName,
                                                ParentTable = _dbTable,
                                                RelatedTable = parentDBTable
                                            };
            foreach (DBColumn pkColumn in parentDBTable.PrimaryKeyDB.Columns)
            {
                DBColumn fkDBColumn = AddColumn(pkColumn.ColumnName);
                fkDBColumn.DataType = pkColumn.DataType;
                fkDBColumn.DataLength = pkColumn.DataLength;
                dbForeignKey.ForeignKeyColumns.Add(new DBForeignKeyColumn
                                                       {
                                                           ParentColumn = fkDBColumn,
                                                           RelatedColumn = pkColumn,
                                                       });
            }
            return dbForeignKey;
        }

        public DBKey AddUniqueKey(string keyName, params string[] columnNames)
        {
            DBKey dbKey = _dbTable.Keys.CreateBusinessObject();
            dbKey.KeyName = keyName;
            foreach (string columnName in columnNames)
            {
                dbKey.AddColumnInfo(AddColumn(columnName));
            }
            return dbKey;
        }

        public DBColumn AddUniqueKeyColumn()
        {
            return AddUniqueKeyColumn(_dbTable.TableName + "_Unique");
        }

        public DBColumn AddUniqueKeyColumn(string columnName)
        {
            DBColumn dbColumn = AddColumn(columnName);
            DBKey dbKey = _dbTable.Keys.CreateBusinessObject();
            dbKey.KeyName = _dbTable.TableName + "_UK";
            dbKey.AddColumnInfo(dbColumn);
            return dbColumn;
        }
    }
}